package com.seed.uaa.util;

import cn.hutool.core.util.StrUtil;
import com.seed.util.StrKit;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PermiUtil {

    /**
     * 将字符串datas转换成按功能分组的map
     * @param datas: 【micro.action:column_op=1,micro.seed.action:column_op=1】
     * @return {'micro.action': [column_op=1, column_op=2]}
     */
    private static Map<String, List<String>> datasToMap(String datas) {
        Map<String, List<String>> ret = new HashMap<>();
        if(StrUtil.isBlank(datas)) return ret;

        for(String item: datas.split(",")) {
            String[] items = StrKit.cutInTwo(item.trim(), ':', false);
            String key = items[0];
            String value = items[1];
            List<String> list = ret.get(key);
            if(list == null) list = new ArrayList<>();
            list.add(value);
            ret.put(key, list);
        }

        return ret;
    }


    private static String mapToDatas(Map<String, List<String>> map) {
        StringBuilder sb = new StringBuilder();
        for(Map.Entry<String, List<String>> entry: map.entrySet()) {
            String key = entry.getKey();
            for(String item: entry.getValue()) {
                if(!sb.isEmpty()) sb.append(',');
                sb.append(key).append(':').append(item);
            }
        }

        return sb.toString();
    }

    /**
     * 将字符串fields转换成按功能分组的map
     * @param fields: 【micro.action:column=1,micro.seed.action:column=1】
     * @return {'micro.action': {column: 1, column: 2}}
     */
    private static Map<String, Map<String, String>> fieldsToMap(String fields) {
        Map<String, Map<String, String>> ret = new HashMap<>();
        if(StrUtil.isBlank(fields)) return ret;

        for(String item: fields.split(",")) {
            String[] items = StrKit.cutInTwo(item.trim(), ':', false);
            String key = items[0];
            String value = items[1];
            Map<String, String> map = ret.get(key);
            if(map == null) map = new HashMap<>();

            String[] keyValue = StrKit.cutInTwo(value, '=', false);
            map.put(keyValue[0], keyValue[1]);
            ret.put(key, map);
        }

        return ret;
    }

    private static String mapToFields(Map<String, Map<String, String>> map) {
        StringBuilder sb = new StringBuilder();
        for(Map.Entry<String, Map<String, String>> entry: map.entrySet()) {
            String key = entry.getKey();
            for(Map.Entry<String, String> e: entry.getValue().entrySet()) {
                if(!sb.isEmpty()) sb.append(',');
                sb.append(key).append(':').append(e.getKey()).append('=').append(e.getValue());
            }
        }

        return sb.toString();
    }

    public static List<String> extract(String datasOrFields, String actionPath) {
        List<String> ret = new ArrayList<>();
        for(String data: datasOrFields.split(",")) {
            String[] items = StrKit.cutInTwo(data.trim(), ':', false);
            String key = items[0];
            String value = items[1];
            if(key.equals(actionPath)) ret.add(value);
        }

        return ret;
    }

    public static void fillFields(Map<String, String> container, String fields, String actionPath) {
        List<String> list = PermiUtil.extract(fields, actionPath);
        for(String item: list) {
            String[] items = StrKit.cutInTwo(item, '=', false);
            container.putIfAbsent(items[0], items[1]);
        }
    }

    public static String edit(String datas, String actionPath, List<String> params) {
        Map<String, List<String>> map = datasToMap(datas);
        if(params.isEmpty()) {
            map.remove(actionPath);
        } else {
            map.put(actionPath, params);
        }
        return mapToDatas(map);
    }

    public static String edit(String datasOrFields, String actionPath, Map<String, String> params) {
        Map<String, Map<String, String>> map = fieldsToMap(datasOrFields);
        if(params.isEmpty()) {
            map.remove(actionPath);
        } else {
            map.put(actionPath, params);
        }
        return mapToFields(map);
    }
}
